import json
import re

import numpy as np
from openai import OpenAI
from text2vec import SentenceModel


class questionAgent:
    def __init__(self, llm, interview_tool):
        self.llm = llm
        self.interview_tool = interview_tool
        self.asked_ids = set()
        self.client = OpenAI(api_key="sk-829463e11b81404a8e2c1c8b2e3cad47", base_url="https://api.deepseek.com")
        self.embedding_model = SentenceModel("shibing624/text2vec-base-chinese")  # 提前初始化模型

    #
    def getProfessionQuestion(self, user_resume, position, positionRequire):
        topicList = self.get_question_topic(user_resume, position, positionRequire)
        questionList = []
        for topic in topicList:
            questions = self.search_question(topic)
            if not questions:
                ai_question = topic.get("query")
            else:
                ai_question = self.select_question(questions, query=topic.get("query"))
            questionList.append(ai_question)
        return questionList

    # 获取问题的主题
    def get_question_topic(self, resume, position, positionRequire):
        prompt = f"""你是一名智能面试官。面试者的求职岗位是{position}
        面试者的简历如下：{resume}
        请结合意向岗位和简历，主要根据岗位要求，分析面试中适合考察的知识点标签（tags）、难度等级（difficulty, 1-3）、关键词（query）。
        要求以列表的形式返回四个JSON，注意只要四个，不要多余或少于四个。
        JSON格式要求（严格JSON）：
        {{
            "tags": ["xxx", "xxx"],
            "difficulty": 1,
            "query": "关键词或简短描述"
        }}
        """
        response = self.client.chat.completions.create(
            model="deepseek-chat",
            messages=[
                {"role": "user", "content": prompt},
            ],
            stream=False
        )
        topics = response.choices[0].message.content.replace("`", "").replace("json", "")
        print("🎯 LLM 返回参数原文:\n", topics)

        # 匹配每一个对象
        matches = re.findall(r'\{.*?\}', topics, flags=re.DOTALL)
        topicList = [json.loads(m) for m in matches]
        # topicList = json.loads(topics)
        print(topicList)
        return topicList


    # 在向量数据库中查找相关的问题
    def search_question(self, params):
        questions = self.interview_tool.search(
            tags=params.get("tags"),
            difficulty=params.get("difficulty"),
            query=params.get("query"),
            exclude_ids=list(self.asked_ids),
            topk=3
        )
        for q in questions:
            self.asked_ids.add(q["id"])
        return questions


    # 选择最相关的问题
    def select_question(self, candidate_questions, query=None):
        print(query)
        if not candidate_questions:
            return '暂时没有更合适的问题，请补充你的技术方向。'

        # 如果没有查询词，则默认选第一个
        if not query:
            return candidate_questions[0]['question']

        # 使用向量相似度，选最相关的
        query_vec = self.embedding_model.encode(query)

        def cosine_similarity(a, b):
            return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

        best_q = None
        best_score = -1

        for q in candidate_questions:
            if q["id"] in self.asked_ids:
                continue  # 跳过已问过的
            q_vec = self.embedding_model.encode(q["question"])
            print(q['question'])
            score = cosine_similarity(query_vec, q_vec)
            if score > best_score:
                best_score = score
                best_q = q

        if best_q:
            return best_q['question'] #最相关的问题
        else:
            return candidate_questions[0]['question'] #默认第一个问题
